using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc.Testing;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using JGSY.CMS.LowCode.Platform.Infrastructure.CmsDbContext;

namespace JGSY.CMS.LowCode.Platform.IntegrationTests.Infrastructure;

/// <summary>
/// 自定义 Web 应用程序工厂，用于集成测试
/// </summary>
/// <typeparam name="TStartup">启动类类型</typeparam>
public class CustomWebApplicationFactory<TStartup> : WebApplicationFactory<TStartup> 
    where TStartup : class
{
    protected override void ConfigureWebHost(IWebHostBuilder builder)
    {
        builder.ConfigureAppConfiguration((context, config) =>
        {
            // 添加测试配置文件
            config.AddJsonFile("appsettings.test.json", optional: false, reloadOnChange: true);
        });

        builder.ConfigureServices(services =>
        {
            // 移除现有的数据库上下文配置
            var descriptors = services.Where(d => 
                d.ServiceType == typeof(DbContextOptions<LowCodeDbContext>) ||
                d.ServiceType == typeof(LowCodeDbContext) ||
                d.ImplementationType?.Name.Contains("Database") == true).ToList();
            
            foreach (var descriptor in descriptors)
            {
                services.Remove(descriptor);
            }

            // 配置测试数据库
            services.AddDbContext<LowCodeDbContext>(options =>
            {
                options.UseSqlite("Data Source=:memory:");
                options.EnableSensitiveDataLogging();
            });

            // 确保应用服务已注册 - 使用已有的扩展方法
            // 如果需要，可以在这里添加额外的服务配置
            
            // 确保数据库创建和种子数据
            var sp = services.BuildServiceProvider();
            using var scope = sp.CreateScope();
            var scopedServices = scope.ServiceProvider;
            
            try
            {
                var db = scopedServices.GetRequiredService<LowCodeDbContext>();
                var logger = scopedServices.GetRequiredService<ILogger<CustomWebApplicationFactory<TStartup>>>();

                db.Database.EnsureCreated();

                try
                {
                    // 这里可以添加测试数据种子
                    SeedTestData(db);
                }
                catch (Exception ex)
                {
                    logger.LogError(ex, "在数据库种子期间发生错误：{Message}", ex.Message);
                }
            }
            catch (Exception ex)
            {
                // 如果无法获取数据库上下文，记录警告但不失败
                Console.WriteLine($"警告：无法初始化测试数据库：{ex.Message}");
            }
        });

        builder.UseEnvironment("Testing");
    }

    /// <summary>
    /// 种子测试数据
    /// </summary>
    /// <param name="context">数据库上下文</param>
    private static void SeedTestData(LowCodeDbContext context)
    {
        // 清理现有数据
        context.Database.EnsureDeleted();
        context.Database.EnsureCreated();

        // 添加测试数据
        // 示例：添加测试用户、角色等
        // context.Users.Add(new User { ... });
        // context.SaveChanges();
    }
}
